package com.scx.oper;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.scx.bean.db.Columns;
import com.scx.bean.db.DataBase;
import com.scx.bean.db.DataSourceConfig;
import com.scx.bean.db.Tables;
import com.scx.util.Iconst;
import com.scx.util.JavaType;


/**
 * 数据库支持类
 * 
 * @author using
 */
public class DBFactoryTable {
	private int dbType; //数据库类型
	private DataSourceConfig dbInfo; //数据库连接信息

	public DBFactoryTable(int dbType, DataSourceConfig dbInfo) {
		this.dbType = dbType;
		this.dbInfo = dbInfo;
	}

	/**
	 * 选择不同的数据库，并获取对应的数据库信息
	 * @param type 类型Iconst类中常量
	 * @param ip 数据库连接IP
	 * @param port 数据库连接端口
	 * @param dbName 数据库名称
	 * @param dbUser 用户名
	 * @param dbPassword 密码
	 */
	public DataBase chooseDatabase() {
		DataBase databaseInfo = null;
		try {
			DataSourceConfig dataSourceConfig = new DataSourceConfig();
			// 选择不同的数据库
			switch (dbType) {
			case Iconst.DB_MSSQL:
				// SQLSERVER
				dataSourceConfig.setDriver("com.microsoft.sqlserver.jdbc.SQLServerDriver");
				dataSourceConfig.setUrl("jdbc:sqlserver://" + dbInfo.getIp() + ":" + dbInfo.getPort() + ";databaseName=" + dbInfo.getDbName() + "");
				dataSourceConfig.setUser(dbInfo.getUser());
				dataSourceConfig.setPass(dbInfo.getPass());
				break;
			case Iconst.DB_ORACLE:
				// ORACLE
				dataSourceConfig.setDriver("oracle.jdbc.driver.OracleDriver");
				dataSourceConfig.setUrl("jdbc:oracle:thin:@" + dbInfo.getIp() + ":" + dbInfo.getPort() + ":"+ dbInfo.getDbName() + "");
				dataSourceConfig.setUser(dbInfo.getUser());
				dataSourceConfig.setPass(dbInfo.getPass());
				break;
			case Iconst.DB_MYSQL :
				// mysql数据库连接
				dataSourceConfig.setDriver("com.mysql.jdbc.Driver");
				dataSourceConfig.setUrl("jdbc:mysql://" + dbInfo.getIp() + ":" + dbInfo.getPort() + "/" + dbInfo.getDbName() + "?useUnicode=true&characterEncoding=UTF-8");
				dataSourceConfig.setUser(dbInfo.getUser());
				dataSourceConfig.setPass(dbInfo.getPass());
				break;
			default:
				break;
			}
			// 获取数据库连接
			Class.forName(dataSourceConfig.getDriver());
			Connection con = DriverManager.getConnection(dataSourceConfig.getUrl(), dataSourceConfig.getUser(), dataSourceConfig.getPass());
			// 数据数据库中具体信息
			databaseInfo = this.getDataBaseInfos(con);
		} catch (Exception e) {
			databaseInfo = new DataBase();
			databaseInfo.setErrorMsg(e.getMessage().replace("\"", "'"));
			//System.out.println("数据库连接失败！" + e.getMessage());
		}
		return databaseInfo;
	}

	/**
	 * 获取数据库所有的信息，表，列，数据类型
	 * @throws Exception 
	 */
	public DataBase getDataBaseInfos(Connection con) throws Exception {
		DataBase dataBaseInfo = new DataBase();
		DatabaseMetaData dmd = con.getMetaData();
		// 数据库名:
		dataBaseInfo.setDatabaseProductName(dmd.getDatabaseProductName());
		// 数据库版本号:
		dataBaseInfo.setDatabaseProductVersion(dmd.getDatabaseProductVersion());
		// 驱动程序
		dataBaseInfo.setDriverName(dmd.getDriverName());
		// 驱动版本
		dataBaseInfo.setDriverVersion(dmd.getDriverVersion());
		// 获取表和列信息
		dataBaseInfo.setListTables(this.getTableInfos(dmd));
		// 获取视图信息
		//dataBaseInfo.setListViews(this.getViewInfos(dmd));
		
		return dataBaseInfo;
	}

	/**
	 * 获取数据库表信息
	 * 
	 * @param dmd
	 * @return
	 * @throws Exception
	 */
	public List<Tables> getTableInfos(DatabaseMetaData dmd) throws Exception {
		List<Tables> listTables = new ArrayList<Tables>();
		ResultSet resTables = null;
		switch (dbType) {
		case Iconst.DB_MSSQL:
			// MSSQLSERVER
			resTables = dmd.getTables(null, null, "%", new String[] { "TABLE" });
			break;
		case Iconst.DB_ORACLE:
			// ORACLE
			resTables = dmd.getTables(null, dbInfo.getUser().toUpperCase(), null, new String[] { "TABLE" });
			break;
		case Iconst.DB_MYSQL :
			// mysql获取表信息参数
			resTables = dmd.getTables(null, null, null, new String[] { "TABLE" });
			break;
		default:
			break;
		}
		while (resTables.next()) {
			Tables table_d = new Tables();
			// 表类别（可为 null）
			table_d.setTableCat(resTables.getString("TABLE_CAT"));
			// 表模式（可为 null）
			table_d.setTableSchem(resTables.getString("TABLE_SCHEM"));
			// 表名
			table_d.setTableName(resTables.getString("TABLE_NAME"));
			// 表名称 表类型。
			table_d.setTableType(resTables.getString("TABLE_TYPE"));
			// 表的解释性注释
			table_d.setTableRemarks(resTables.getString("REMARKS"));
			table_d.setListColumns(this.getColumnInfos(dmd, resTables.getString("TABLE_NAME")));
			listTables.add(table_d);
		}
		return listTables;
	}
	
	/**
	 * 获取数据库视图信息
	 */
	public List<Tables> getViewInfos(DatabaseMetaData dmd) throws Exception {
		List<Tables> listTables = new ArrayList<Tables>();
		ResultSet resTables = null;
		// mysql获取表信息参数
		resTables = dmd.getTables(null, null, null, new String[] { "VIEW" });
		while (resTables.next()) {
			Tables table_d = new Tables();
			// 表类别（可为 null）
			table_d.setTableCat(resTables.getString("TABLE_CAT"));
			// 表模式（可为 null）
			table_d.setTableSchem(resTables.getString("TABLE_SCHEM"));
			// 表名
			table_d.setTableName(resTables.getString("TABLE_NAME"));
			// 表名称 表类型。
			table_d.setTableType(resTables.getString("TABLE_TYPE"));
			// 表的解释性注释
			table_d.setTableRemarks(resTables.getString("REMARKS"));
			table_d.setListColumns(this.getColumnInfos(dmd, resTables.getString("TABLE_NAME")));
			listTables.add(table_d);
		}
		return listTables;
	}

	/**
	 * 获取数据库表中列信息
	 * 
	 * @param dmd
	 * @return
	 * @throws Exception
	 */
	public List<Columns> getColumnInfos(DatabaseMetaData dmd, String tableName) throws Exception {
		List<Columns> listColumns = new ArrayList<Columns>();
		ResultSet resColumns = dmd.getColumns(null, "%", tableName, "%");
		while (resColumns.next()) {
			Columns columns_d = new Columns();
			// 列名
			columns_d.setColumnName(resColumns.getString("COLUMN_NAME"));
			// 表名称
			columns_d.setTableName(resColumns.getString("TABLE_NAME"));
			// java.sql.Types 的 SQL 类型
			columns_d.setDataType(resColumns.getInt("DATA_TYPE"));
			// 类型名称
			columns_d.setDataTypeName(JavaType.getType(resColumns.getInt("DATA_TYPE")));
			// 列大小
			columns_d.setColumnSize(resColumns.getString("COLUMN_SIZE"));
			// 描述
			columns_d.setRemarks(resColumns.getString("REMARKS"));
			listColumns.add(columns_d);
		}
		return listColumns;
	}

	/**
	 * 获取数当前数据库支持的数据类型 --暂未实现
	 * 
	 * @param con
	 */
	public void getDatabaseTypeInfos(Connection con) {
		try {
			DatabaseMetaData dmd = con.getMetaData();
			// 数据库的数据类型列表
			ResultSet rsTypeInfo = dmd.getTypeInfo();
			System.out.println("数据字段类型类型列表");
			while (rsTypeInfo.next()) {
				System.out.println(rsTypeInfo.getString("TYPE_NAME"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
